const fs = require('fs');

const path = require('path');

//错误处理，按照错误码退出
const processError = require('../../common/error');

//git info 对象
const git = require('../git/index');

//生成MD5值
const md5sumFactory = require('./md5sum');

//p系列wiki的模板
const pSeriesWikiTpl = require('./pSeriesWikiTpl');

const message = require('../../common/ansi');

const {OUTPUT_DIR, OUTPUT_NAME} = require('../../common/constans');

const log = require('../../common/log');

class Pack {

  constructor({mode,config,versionConfig,cwd,...argvs}) {

    this.mode = mode;

    // 用户输入的参数
    this.argvs = argvs;

    // 配置文件
    this.config = config;

    // 版本文件
    this.versionConfig = versionConfig;

    this.cwd = cwd;

    this.init();

  }

  /**
   * 打印与记录日志
   * @param {*} msg 消息
   */
  printInfoAndLog(msg,type='info',logType=3){

    message[type](msg);

    log(logType,msg);

  }

  /**
   * 清除文件夹内容
   * @param {*} path 文件夹路径
   * @param {*} onlyChild 是否只清除子级内容，不删除自身文件夹
   */
  clearFileAndDir(path,onlyChild){

    let parent;
  
    if(onlyChild){
  
      parent = path;
  
    }
  
    del(path);
  
    function del(path){
  
      let files = [];
  
      if(fs.existsSync(path)){
  
          files = fs.readdirSync(path);
  
          files.forEach((file, index) => {
  
              let curPath = path + "/" + file;
  
              if(fs.statSync(curPath).isDirectory()){
  
                del(curPath); //递归删除文件夹
  
              } else {
  
                  fs.unlinkSync(curPath); //删除文件
  
              }
  
          });
  
          if(!onlyChild && path !== parent)fs.rmdirSync(path);
          
      }
  
    }
    
  }

  /**
   * 初始化参数
   */
  init() {

    // [OUTPUT_DIR]:outputDir 解构动态属性   https://www.cnblogs.com/xiaonian8/p/13847167.html
    let { platform, [OUTPUT_DIR]:outputDir = '', [OUTPUT_NAME]:outputName,version } = this.argvs;
    let sourceDir;

    // 输出的文件名称
    let filename = outputName || '';

    let ysmodulesPath = null;

    this.printInfoAndLog('Pack对象 init方法 mode 是:'+this.mode);

    sourceDir=this.versionConfig[platform]['path'];

    // 例如：p_series-1.0.1
    filename += platform + '-'+ version;
    
    let inputDirPath = path.join(this.cwd, sourceDir);

    if (!sourceDir || !fs.existsSync(inputDirPath)) {

      processError('程序输入路径错误,路径为:'+inputDirPath);

    }

    this.printInfoAndLog('Pack对象 init方法 inputDirPath 是:'+inputDirPath);

    let distDirPath = path.resolve(this.cwd, outputDir);

    fs.existsSync(distDirPath) || this.mkdirsSync(distDirPath);

    this.printInfoAndLog('Pack对象 init方法 distDirPath 是:'+distDirPath);

    // 调用打包方法
    this.pack({

      ...this.argvs,

      sourceDir,

      inputDirPath,

      distDirPath,

      outputName,

      outputDir,

      ysmodulesPath,

      filename

    });

  }

  mkdirsSync(dirname) {  
    
    if (fs.existsSync(dirname)) {  

        return true;  

    } else {  

        if (this.mkdirsSync(path.dirname(dirname))) {  

            fs.mkdirSync(dirname);  

            return true;  

        }  

    }  

  } 

  mkdir(path) {

    if (!fs.existsSync(path)) {

      try {

        fs.mkdirSync(path);

        this.printInfoAndLog('创建文件夹：'+path+' 成功','success');
        
      } catch (error) {
        
        this.printInfoAndLog('创建文件夹：'+path+' 失败','error');

        processError(error);

      }

    }

    return path

  }

  pack(params) {

    let { distDirPath, filename, platform, project, version, branch, lastVersion, memo } = params;

    //创建一最终打包文件的输出流
    // let output = fs.createWriteStream(tarPath);

    const filePath = path.join(distDirPath, 'pbxweb-'+filename);

    // gdpr文件路径
    const gdprAdminPath = path.join(distDirPath, './public/gdpr/admin_version.conf');

    const gdprExtPath = path.join(distDirPath, './public/gdpr/ext_version.conf');

    // 根据文件生成md5值并写入wiki文件中
    const md5sum = md5sumFactory(`${filePath}.tar`);

    const { user } = git.gitInfo({lastVersionTag:`${project}-${platform}-${lastVersion}`,versionTag:`${project}-${platform}-${version}`},this.cwd);

    let wikiOption = { filePath, gdprAdminPath, gdprExtPath, branch, moduleName: filename, user, version, md5sum, memo };

    pSeriesWikiTpl(wikiOption, ({filePath}) => {

      this.printInfoAndLog(filePath + '写入成功！','success');

      this.versionConfig[platform].version = version;

      this.versionConfig[platform].last_version = lastVersion;

    });
  }

}

module.exports = Pack;